package taw2012;

import java.sql.*;
import java.util.Calendar;

/**
 *
 * @author ale
 */
public class GestioneDB {    
    //Attributi
    private static Connection connessione = null;
    private static Boolean existTables=false;    
    //Metodo Costruttore
    public GestioneDB(){        
    }
    
    public void connetti(){
        try{ 
            /*Bisogna importare la libreria derby.jar da /usr/local/glassfish/javaDB/lib/*/
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            connessione = DriverManager.getConnection("jdbc:derby:MeteoDB;create=true");
        }catch(Exception e){
            System.err.println(e);
        }                 
    }

    public void disconnetti(){
        if (connessione!=null){
            try {
                connessione.close();
                connessione=null;
            } catch (SQLException ex) {
                System.err.println("Errore nella disconnessione!");
            }
        }
    }
    
    /*metodo che inizializza il database creando le tabelle se non esistono*/
    public void inizializzaDB(){
        /*mi connetto alla base di dati */
        this.connetti();        
        try{
            /* Controllo se la base di dati è già stata creata, in caso contrario la creo */
            boolean citta = false;
            boolean previsioni = false;
            boolean regioni = false;
            ResultSet rsTabelle = connessione.getMetaData().getTables(null, null, null, null);            
            /*scorro tutte le tabelle*/
            while (rsTabelle.next()) {
                /* controllo che le tabelle esistano, riporto tramite una flag quelle non ancora create*/
                if (rsTabelle.getString("TABLE_NAME").compareToIgnoreCase("citta") == 0) {
                    citta = true;
                }
                if (rsTabelle.getString("TABLE_NAME").compareToIgnoreCase("previsioni") == 0) {
                    previsioni = true;
                }
                if (rsTabelle.getString("TABLE_NAME").compareToIgnoreCase("regioni") == 0) {
                    regioni = true;
                }
            }
           
           /* Nel caso non sia stata trovata una tabella allora è necessario crearla*/
           if (!regioni) {
                String sql1 = "CREATE TABLE Regioni "
                            + "(Id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"                            
                            + " Nome VARCHAR(30) NOT NULL,"
                            + " PRIMARY KEY (Nome))";                            
                Statement ps = connessione.createStatement();
                ps.executeUpdate(sql1);
                System.err.println("Tabella regioni creata con successo.");
                ps.close();
           }
           if (!citta) {
                String sql2 =  "CREATE TABLE Citta "
                            + "(Id INTEGER NOT NULL,"                            
                            + " Nome VARCHAR(60) NOT NULL,"
                            + " Sigla VARCHAR(2) NOT NULL,"
                            + " Regione VARCHAR(30) NOT NULL,"
                            + " PRIMARY KEY (Id),"
                            + " FOREIGN KEY (Regione) REFERENCES Regioni(Nome))";
                Statement ps = connessione.createStatement();
                ps.executeUpdate(sql2);
                System.err.println("Tabella citta creata con successo.");
                ps.close();
           }
           if (!previsioni) {
                String sql3 =  "CREATE TABLE Previsioni "
                            + "(Id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"                            
                            + " Data DATE NOT NULL,"
                            + " Previsione VARCHAR(40) NOT NULL,"
                            + " Tmin VARCHAR(10) NOT NULL,"
                            + " Tmax VARCHAR(10) NOT NULL,"
                            + " Precipitazioni VARCHAR(10) NOT NULL,"
                            + " Vento VARCHAR(10) NOT NULL,"
                            + " Pressione VARCHAR(10) NOT NULL,"
                            + " Quotazero VARCHAR(10) NOT NULL,"
                            + " IdCitta INTEGER NOT NULL,"
                            + " FOREIGN KEY (IdCitta) REFERENCES citta(Id))";
                Statement ps = connessione.createStatement();
                ps.executeUpdate(sql3);
                System.err.println("Tabella previsioni creata con successo.");
                ps.close();
           }           
           existTables=true;
           this.disconnetti();           
       } catch (Exception e) {
           System.err.println("Errore nella creazione delle tabelle!"+e);
       }
    }
    
    /*-------------------------------------------------------------------------------------------------*/
    /*--------------------PROCEDURE PER SALVARE LE CITTA' DA CSV----------------------------------------*/
    /*--------------------------------------------------------------------------------------------------*/
    
    
    /*funzione che inserisce nel database una città*/
    public synchronized void inserisciCitta(int id, String nome, String provincia, String regione){
       try{                
            PreparedStatement ps = connessione.prepareStatement("INSERT INTO citta (Id,Nome,Sigla,Regione) VALUES (?,?,?,?)");
            ps.setInt(1,id);
            ps.setString(2,nome);
            ps.setString(3,provincia);
            ps.setString(4,regione);
            ps.executeUpdate();
            ps.close();            
        } catch (SQLException ex) {
            System.out.println("Errore nell'inserimento delle città nel db "+ nome);
        }
    }
    
    /*Cerca una città nel db e restituisce true o false se esiste*/
    public boolean esisteCitta(int id,String nome){       
       boolean trovato=false;
       try{    
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Citta WHERE Id=?");
            ps.setInt(1, id);            
            ResultSet res = ps.executeQuery();
            while(res.next())
                trovato=true;
            ps.close();            
        } catch (SQLException ex) {
            System.err.println("Errore nella ricerca della regione");
            System.out.println("--"+nome+"--");
        }       
        return trovato;
    }
    
    /*funzione che inserisce nel database una regione*/
    public void inserisciRegione(String regione){       
       try{    
            PreparedStatement ps = connessione.prepareStatement("INSERT INTO Regioni (Nome) VALUES (?)");
            ps.setString(1, regione);
            ps.executeUpdate();            
            ps.close();            
        } catch (SQLException ex) {
            System.err.println("Errore nell'inserimento della regione nel db -- "+regione+"");
        }       
    }
    
    public boolean esisteRegione(String regione){       
       boolean trovato=false;
       try{    
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Regioni WHERE Nome=?");
            ps.setString(1, regione);
            ResultSet res = ps.executeQuery();
            if(res.next())
                trovato=true;                
            ps.close();            
        } catch (SQLException ex) {
            System.err.println("Errore nella ricerca della regione");
            System.out.println("--"+regione+"--");
        }        
        return trovato;
    }
    
    /*-------------------------------------------------------------------------------------------------*/
    /*--------------------PROCEDURE PER GESTIONE DELLE PREVISIONI----------------------------------------*/
    /*--------------------------------------------------------------------------------------------------*/
    
    public void inserisciPrevisione(Previsione prev){
        try{                
            PreparedStatement ps = connessione.prepareStatement("INSERT INTO Previsioni (Data,Previsione,Tmin,Tmax,Precipitazioni,Vento,Pressione,Quotazero,IdCitta) VALUES (?,?,?,?,?,?,?,?,?)");
            Calendar cal = prev.getDataPrevisione();
//            int giorno = cal.get(Calendar.DAY_OF_MONTH);
//            int mese = cal.get(Calendar.MONTH)+1;
//            int anno = cal.get(Calendar.YEAR);
            Date x = new Date(cal.getTimeInMillis());
            ps.setDate(1,x);
            ps.setString(2,prev.getPrevisione());
            ps.setString(3,prev.gettMin());
            ps.setString(4,prev.gettMax());
            ps.setString(5,prev.getPercentualePrecipitazioni());
            ps.setString(6,prev.getVentoKmh());
            ps.setString(7,prev.getPressione());
            ps.setString(8,prev.getQuotaZero());
            ps.setInt(9, prev.getId());
            ps.executeUpdate();
            ps.close();  
            System.out.println("previsione inserita\n"+prev);
        } catch (SQLException ex) {
            System.out.println("Errore nell'inserimento della previsione del...............................nel db ");
            System.err.println(ex);
        }

    }
    
    /**
     * Metodo per controllare se una previsione esiste già
     */
    public boolean esistePrevisione(Previsione p){
        boolean trovata = false;
        Calendar cal = p.getDataPrevisione();
//        int giorno = cal.get(Calendar.DAY_OF_MONTH);
//        int mese = cal.get(Calendar.MONTH)+1;
//        int anno = cal.get(Calendar.YEAR);
        Date x = new Date(cal.getTimeInMillis());
        try{
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Previsioni WHERE IdCitta=? AND Data=?");
            ps.setInt(1,p.getId());
            ps.setDate(2,x);
            ResultSet rs = ps.executeQuery();
            if(rs.next())
                trovata=true;
        }catch(SQLException e){
            System.out.println("Errore nella query - EsistePrevisione();");
        }
        return trovata;
    }
    public void aggiornaPrevisioniDB(){
    try{ 
        PreparedStatement ps = connessione.prepareStatement("SELECT Id FROM Citta");
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            Previsione[] p = ParsingHtml.estraiPrevisioneLocalita(rs.getInt("Id"));
            for(int i=0; i < 7; i++){
                if (!esistePrevisione(p[i])){
                    inserisciPrevisione(p[i]);
                }else{
                    aggiornaPrevisione(p[i]);
                }
            }
            
            }
        }
    catch(SQLException e){
            System.out.println("Errore nella query;");
        }
    catch(Exception e){
        System.out.println("Errore nel parsing"+e);
    }    
   }
    /**
     * La funzione aggiorna una previsione nel database.
     * @param prev Previsione
     * @return Sovrascrive a quella già esistente
     */
    public void aggiornaPrevisione(Previsione prev){
        Calendar cal = prev.getDataPrevisione();
//        int giorno = cal.get(Calendar.DAY_OF_MONTH);
//        int mese = cal.get(Calendar.MONTH)+1;
//        int anno = cal.get(Calendar.YEAR);
//        
        Date x = new Date(cal.getTimeInMillis());
        try{
            PreparedStatement ps = connessione.prepareStatement("UPDATE Previsioni SET Pressione=?, Previsione=?, Precipitazioni=?, Vento=?, Tmin=?, Tmax=?, Quotazero=? WHERE IdCitta=? AND Data=?");
            ps.setDate(9,x);
            ps.setString(2,prev.getPrevisione());
            ps.setString(5,prev.gettMin());
            ps.setString(6,prev.gettMax());
            ps.setString(3,prev.getPercentualePrecipitazioni());
            ps.setString(4,prev.getVentoKmh());
            ps.setString(1,prev.getPressione());
            ps.setString(7,prev.getQuotaZero());
            ps.setInt(8, prev.getId());
 
            ps.executeUpdate();
            System.out.println("aggiornamento eseguito\n"+ prev);
        }catch(SQLException e){
            System.out.println("Errore nell'aggiornamento delle previsioni");
            System.err.println(e);
        }
        
    }
    
    
    /*-------------------------------------------------------------------------------------------------*/
    /*--------------------PROCEDURE PER LA STAMPA DEL DATABASE----------------------------------------*/
    /*--------------------------------------------------------------------------------------------------*/
    
    public void stampaRegioni(){
        try{    
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Regioni");
            ResultSet res = ps.executeQuery();
            System.out.println("----------------------------------------------");
            System.out.println("---------------REGIONI------------------------");
            System.out.println("----------------------------------------------");
            while(res.next()){
                System.out.println("---"+res.getInt("Id")+" - "+res.getString("Nome")+"");
            }
            System.out.println("----------------------------------------------");
            ps.close();
         } catch (SQLException ex) {
            System.err.println("Errore nella ricerca della regione");
            
        }
    }
    public void stampaCitta(){
        try{            
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Citta");
            ResultSet res = ps.executeQuery();
            System.out.println("----------------------------------------------");
            System.out.println("-----------------CITTA------------------------");
            System.out.println("----------------------------------------------");
            while(res.next()){
                System.out.println("---"+res.getInt("Id")+" - "+res.getString("Nome")+" - "+res.getString("Sigla")+" - "+res.getString("Regione")+"");
            }
            System.out.println("----------------------------------------------");
            ps.close();
            
        } catch (SQLException ex) {
            System.err.println("Errore nella ricerca della regione");            
        }
    }
  public void stampaPrevisioni(){
        try{            
            PreparedStatement ps = connessione.prepareStatement("SELECT * FROM Previsioni");
            ResultSet res = ps.executeQuery();
            System.out.println("----------------------------------------------");
            System.out.println("---------------PREVISIONI----------------------");
            System.out.println("----------------------------------------------");
            while(res.next()){
                System.out.println("---"+res.getInt("Id")+";\t"+res.getInt("IdCitta")+";\t"+res.getDate("Data")+";\t"+res.getString("Previsione")+"\t\t"+res.getString("Tmin")+";\t"+res.getString("Tmax")+";\t"+res.getString("Precipitazioni")+";\t"+res.getString("Vento")+";\t"+res.getString("Pressione")+";\t"+res.getString("Quotazero"));
            }
            System.out.println("----------------------------------------------");
            ps.close();
            
        } catch (SQLException ex) {
            System.err.println("Errore nella ricerca della regione");            
        }
    } 
    
}
